/*
 * Copyright (c) 2009-2013 EvTech Project
 * All rights reserved.
 * 
 * This file is part of LModeller.
 *
 * LModeller is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version.
 *
 * LModeller is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LModeller.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package fi.honkalampisaatio.lmodeller.ui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import fi.honkalampisaatio.lmodeller.sound.VoicePlayer;
import glapp.GLApp;

import org.lwjgl.opengl.GL11;
import org.lwjgl.util.Rectangle;

public abstract class UIElement {
	Rectangle rec;
	String key;
	boolean isSoundOn, isVisible;
	String actionCommand = null;

	protected ActionListener actionListener = null;

	public UIElement(Rectangle rectangle) {
		this.rec = rectangle;
		isSoundOn = false;
		isVisible = true;
	}
	
	public abstract void paint();
	
	public void setVisible(boolean isVisible)
	{
		this.isVisible = isVisible;
	}

	public void render()
	{
		if(isVisible)
			paint();
	}
	
	public void mouseDown(int x, int y)
	{
		if(contains(x, y) && isVisible)
		{
			ActionEvent action = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand);
			fireActionEvent(action);
		}
	}
	
	public void addActionListener(ActionListener l)
	{
		actionListener = l;
	}
	
	public void removeActionListener(ActionListener listener) {
		if (this.actionListener == listener) {
			this.actionListener = null;
		}
	}
	
	protected void fireActionEvent(ActionEvent ae) {
		if (this.actionListener != null)
			this.actionListener.actionPerformed(ae);
	}

	public void setActionCommand(String actionCommand)
	{
		this.actionCommand = actionCommand;
	}

	public String getActionCommand()
	{
		return actionCommand;
	}
	
	public void setToolTipSound(String soundFilePath)
	{
		key = VoicePlayer.getInstance().addVoice(soundFilePath);
	}

	public void setToolTipSentence(String sentence)
	{
		key = VoicePlayer.getInstance().addTTSVoice(sentence);
	}
	
	
	public Rectangle getBounds() {
		return rec;
	}

	public void setBounds(Rectangle rectangle) {
		this.rec = rectangle;
	}

	public boolean contains(int x, int y)
	{
		if(rec.contains(x, y))
		{
			return true;
		}
		else 
		{
			return false;
		}
	}

    public void mouseMove(int x, int y) {
		if(key!=null && rec.contains(x, y) && !isSoundOn && isVisible)
		{
			Thread t = new Thread(new Runnable() {

				@Override
				public void run() {
					isSoundOn = true;
					VoicePlayer.getInstance().play(key);
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					isSoundOn = false;
				}});
			t.start();
		}
    }
    
    public static void fillRect(int x, int y, float w, float h) {
    	int z = 0;
		GL11.glPushMatrix();
        GLApp.setOrthoOn();
    	// preserve current settings
    	GL11.glPushAttrib(GL11.GL_TEXTURE_BIT | GL11.GL_LIGHTING_BIT);
        // de-activate texture and light
        GL11.glDisable(GL11.GL_TEXTURE_2D);
        GL11.glDisable(GL11.GL_LIGHTING);
        // draw the rectangle
        GL11.glBegin(GL11.GL_QUADS);
        {
            GL11.glVertex3f( (float)x, (float)y, (float)z);
            GL11.glVertex3f( (float)x+w, (float)y, (float)z);
            GL11.glVertex3f( (float)x+w, (float)y+h, (float)z);
            GL11.glVertex3f( (float)x, (float)y+h, (float)z);
            GL11.glVertex3f( (float)x, (float)y, (float)z);
        }
        GL11.glEnd();
        // re-enable settings
        GLApp.popAttrib();
        // restore the previous perspective and model views
        GLApp.setOrthoOff();
        GL11.glPopMatrix();
    }

    /**
     * Draw a textured quad in Ortho mode (2D) at the given xy, scaled to
     * the given width and height.  Depth test is turned off so quad will
     * be drawn on top of the current scene.  Quad will be drawn
     * with current light and material if any are active.
     * <BR>
     * @ee loadImage()
     */
    public static void drawQuad(int textureHandle, int x, int y, float w, float h) {
        // activate the specified texture
        GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureHandle);
        // prepare to render in 2D
        GLApp.setOrthoOn();
        // draw the textured quad
        GL11.glNormal3f(0.0f, 0.0f, 1.0f); // normal faces positive Z
        GL11.glBegin(GL11.GL_QUADS);
        {
            GL11.glTexCoord2f(0f, 0f);
            GL11.glVertex3f( (float)x, (float)y, (float)0);
            GL11.glTexCoord2f(1f, 0f);
            GL11.glVertex3f( (float)x+w, (float)y, (float)0);
            GL11.glTexCoord2f(1f, 1f);
            GL11.glVertex3f( (float)x+w, (float)y+h, (float)0);
            GL11.glTexCoord2f(0f, 1f);
            GL11.glVertex3f( (float)x, (float)y+h, (float)0);
        }
        GL11.glEnd();
        // restore the previous perspective and model views
        GLApp.setOrthoOff();
    }
}
